package td;

import java.util.ArrayList;
import java.util.Random;

import ui.FieldView;
import ui.Viewable;

/*
 * Class for fields. Manages elements on the field.
 * */
public class Field {
	/* List of elements on the field */
	private ArrayList<FieldElement> elements;
	/* List of all neighbouring fields */
	public ArrayList<Field> neighbours;
	/* List of neighbouring fields where enemies can step */
	public ArrayList<Field> nextSteppable;
	public boolean hasTrap;
	public boolean hasTower;
	public boolean isRoad;
	public boolean isStartPoint;
	public boolean isEndPoint;
	public Viewable viewable;

	public Field() {
		elements = new ArrayList<FieldElement>();
		neighbours = new ArrayList<Field>();
		nextSteppable = new ArrayList<Field>();
		viewable = new FieldView(this);
	}

	public void addElement(FieldElement element) {
		this.elements.add(element);
		this.viewable.update();
	}

	public void removeElement(FieldElement element) {
		this.elements.remove(element);
		this.viewable.update();
	}

	/*
	 * Gives a random field from the nextSteppable list to the enemy, so they
	 * can step there.
	 */
	public Field getSteppable() {
		Random r = new Random();
		return this.nextSteppable.get(r.nextInt(nextSteppable.size()));
	}

	/*
	 * Gives a random "backward" field where the WindTrap can push
	 * enemies back. Distance depends on knockback level.
	 */
	public Field getPushbackField(int pushback) {
		Random r = new Random();
		int i = 0;
		ArrayList<Field> backFields = new ArrayList<Field>();
		Field pbField = new Field();
		Field current = this;
		while (i < pushback) {
			backFields.clear();
			for (int j = 0; j < current.neighbours.size(); j++) {
				if (!current.nextSteppable.contains(current.neighbours.get(j)) && current.neighbours.get(j).isRoad) {
					backFields.add(current.neighbours.get(j));
				}
			}
			current = backFields.get(r.nextInt(backFields.size()));
			i++;
		}
		pbField = backFields.get(r.nextInt(backFields.size()));
		return pbField;
	}

	/* If the field hasTrap, this method returns the field's trap. */
	public Trap getTrap() {
		int i = 0;
		while (!(this.elements.get(i) instanceof Trap)) {
			i++;
		}
		return (Trap) this.elements.get(i);
	}

	/* If the field hasTower, this method returns the field's tower. */
	public Tower getTower() {
		int i = 0;
		while (!(this.elements.get(i) instanceof Tower)) {
			i++;
		}
		return (Tower) this.elements.get(i);
	}
	
	/*Returns list of enemies on the field.*/
	public ArrayList<Enemy> getEnemies() {
		ArrayList<Enemy> enemies = new ArrayList<Enemy>();
		for (int i = 0; i < elements.size(); i++) {
			if (elements.get(i) instanceof Enemy) {
				enemies.add((Enemy) elements.get(i));
			}
		}
		return enemies;
	}
	
	public ArrayList<FieldElement> getElements(){
		return this.elements;
	}
}
